package com.javacoo.function;

/**
 * 自定义函数
 * <li></li>
 *
 * @author: duanyong@jccfc.com
 * @since: 2020/8/4 14:40
 */
public interface Function<T,U> {
    U apply(T t);
    /**
     * 复合函数
     * <li>先执行待复合函数,其结果作为参数传入原函数</li>
     * @author duanyong@jccfc.com
     * @date 2020/8/4 15:52
     * @param f: 待复合函数
     * @return: com.javacoo.function.Function<V,U>
     */
    default <V> Function<V,U> compose(Function<V,T> f){
        return x->apply(f.apply(x));
    }
    /**
     * 组合函数
     * <li>先执行原函数,其结果作为参数传入待组合函数</li>
     * @author duanyong@jccfc.com
     * @date 2020/8/4 16:25
     * @param f:待组合函数
     * @return: com.javacoo.function.Function<T,V>
     */
    default <V> Function<T,V> andThen(Function<U,V> f){
        return x->f.apply(apply(x));
    }

    static <T> Function<T,T> identity(){
        return t -> t;
    }

    static <T,U,V> Function<V,U> compose(Function<T,U> f,Function<V,T> g){
        return x->f.apply(g.apply(x));
    }

    static <T,U,V> Function<T,V> andThen(Function<T,U> f,Function<U,V> g){
        return x->g.apply(f.apply(x));
    }

    static <T,U,V> Function<Function<T,U>,Function<Function<U,V>,Function<T,V>>> compose(){
        return x->y->y.compose(x);
    }

    static <T,U,V> Function<Function<T,U>,Function<Function<V,T>,Function<V,U>>> andThen(){
        return x->y->y.andThen(x);
    }

    static <T,U,V> Function<Function<U,V>,Function<Function<T,U>,Function<T,V>>> higherCompose(){
        return (Function<U,V> x)->(Function<T,U> y)->(T z)->x.apply(y.apply(z));
    }

    static <T,U,V> Function<Function<T,U>,Function<Function<U,V>,Function<T,V>>> higherAndThen(){
        return x->y->z->y.apply(x.apply(z));
    }
}
